package cn.mabach.oauth2.config;


import cn.mabach.oauth2.mobile.SmsCodeSecurityConfig;
import cn.mabach.oauth2.qq.QQSecurityConfig;
import cn.mabach.oauth2.validateCode.imageCode.ValidateCodeOnceFilter;


import cn.mabach.oauth2.properties.SecurityProperties;

import cn.mabach.oauth2.validateCode.smsCode.SmsCodeOnceFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;


@EnableWebSecurity // 开启springsecurity过滤链 filter
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private UserDetailsService customUserDetailsService;

    @Autowired
    private AuthenticationFailureHandler customAuthenticationFailureHandler;
    @Autowired
    private AuthenticationSuccessHandler customAuthenticationSuccessHandler;
    @Autowired
    private SecurityProperties securityProperties;


    @Autowired
    private SmsCodeSecurityConfig smsCodeSecurityConfig;
    @Autowired
    private QQSecurityConfig qqSecurityConfig;
    @Autowired
    private ValidateCodeOnceFilter validateCodeOnceFilter;
    @Autowired
    private SmsCodeOnceFilter smsCodeOnceFilter;
    @Autowired
    private PersistentTokenRepository persistentTokenRepository;

    @Autowired
    private MyLogoutSuccessHandler myLogoutSuccessHandler;





    /**
     * 认证管理器：
     * 1. 认证信息（用户名，密码）
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService); //账号密码 交给UserDetailsService 校验
    }


    /**
     * 配置拦截的资源
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        配置图形验证码过一次性滤器属性


//配置smsCode一次性滤器属性



        http.addFilterBefore(smsCodeOnceFilter,UsernamePasswordAuthenticationFilter.class). //注入smsCode一次性过滤器
                addFilterBefore(validateCodeOnceFilter,UsernamePasswordAuthenticationFilter.class)//注入验证码校验一次性过滤器,
                .formLogin()//以表单方式登录
                .loginPage(securityProperties.getBrowser().getLoginPage()) //设置登录页面
                .loginProcessingUrl("/login") // 登录后提交的请求, 默认是/login
                .successHandler(customAuthenticationSuccessHandler)//设置认证成功处理器
                .failureHandler(customAuthenticationFailureHandler)//设置认证失败处理器
                .and()
                .sessionManagement()
                .invalidSessionUrl("/toLogin") //session过期后的跳转地址
                .maximumSessions(1) //最多允许用户在一个地方登录
                .and()
                .and()
                .rememberMe() //记住我
                .tokenRepository(persistentTokenRepository) //记住我token
                .tokenValiditySeconds(securityProperties.getBrowser().getRememberMeSeconds()) //记住我过期时间
                .userDetailsService(customUserDetailsService) //记住我
                .and()
                .authorizeRequests()

                .antMatchers("/**").permitAll() //配置放行的地址

                ; //其余所有请求都要通过身份认证才可以访问

//        securityProperties.getBrowser().getLoginPage()
//                ,"/login","/logout","/toLogin/mobile",
//                "/code/*","/login/mobile","/mobile/login",
//                "/static/css/**","/static/js/**","toLogin/mobile",
//                "/toQQLogin","/qqloginback","/session/invalid",
//                "/relateQQ","/register/qq","/toInfo","/prelogin"

        http.logout()
                .logoutUrl("/logout") // 退出请求路径
//                .logoutSuccessUrl("/toLogin"); //退出成功后跳转地址
                .logoutSuccessHandler(myLogoutSuccessHandler)//配置登录成功后处理器，可以在里面写日志
                .deleteCookies("JSESSIONID"); //退出成功后删除浏览器cookies

//        注入自定义的手机验证器到过滤器链上



//        禁用csrf
        http.csrf().disable();

// 将SmsCodeSecurityConfig封装进HttpSecurity中使短信验证码过滤器生效


        http.apply(smsCodeSecurityConfig);
        http.apply(qqSecurityConfig);
    }



// ————————————————————————————————————————————————————————————————————————————————————————————

    /**
     * password模式需要配置这个bean
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


}
